package com.tianql.service;

import com.tianql.core.ApiResult;
import com.tianql.feign.AccountFeign;
import com.tianql.feign.StorageFeign;
import com.tianql.mapper.OrderTblMapper;
import com.tianql.pojo.OrderTbl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.seata.core.context.RootContext;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * @Author 田起立
 * @Date 2024/6/11 15:46
 * @Description:
 */
@Service
@Slf4j
public class OrderServiceImpl {
    @Autowired
    private OrderTblMapper orderTblMapper;
    @Autowired
    private AccountFeign accountFeign;
    @Autowired
    private StorageFeign storageFeign;
    @Autowired
    private RedissonClient redissonClient;
    @GlobalTransactional(rollbackFor = Exception.class)
    public void createOrder(OrderTbl orderTbl) throws InterruptedException {
        RLock lock = redissonClient.getLock("lock:commodity:" + orderTbl.getCommodityCode());
        boolean isLocked = lock.tryLock(5, 10, TimeUnit.SECONDS); // 最多等待5秒，锁10秒
        if (isLocked) {
            try {
                ApiResult apiResult = storageFeign.getCount(orderTbl.getCommodityCode());
                int count = (int) apiResult.getData();
                if (count > orderTbl.getCount()) {
                    // 状态为未完成
                    orderTbl.setStatus("N");
                    orderTblMapper.insert(orderTbl);
                    // 减库存
                    storageFeign.deduct(orderTbl.getCommodityCode(), orderTbl.getCount());
                    // 减少金额
                    accountFeign.debit(orderTbl.getUserId(), orderTbl.getCount() * orderTbl.getMoney());
                    if (orderTbl.getCount() > 5) {
                        throw new RuntimeException("模拟库存扣减后的异常");
                    }
                    // 修改订单状态，完成
                    orderTbl.setStatus("C");
                    orderTblMapper.updateById(orderTbl);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                if (lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        }

    }
}
